package com.mystudy.gmall.realtime.utils

import java.util.Properties

import io.searchbox.client
import io.searchbox.client.{JestClient, JestClientFactory}
import io.searchbox.client.config.HttpClientConfig
import io.searchbox.core.{Bulk, BulkResult, Index, Search, SearchResult}

object MyESUtil {
  private val properties: Properties = MyPropertiesUtil.load("config.properties")
  val es_url = properties.getProperty("elasticSearch.url")

  private var factory:  JestClientFactory=null;

  def getClient:JestClient ={
    if(factory==null)build();
    factory.getObject

  }

  def  build(): Unit ={
    factory=new JestClientFactory
    factory.setHttpClientConfig(new HttpClientConfig.Builder(es_url)
      .multiThreaded(true)
      .maxTotalConnection(20)
      .connTimeout(10000).readTimeout(1000).build())
  }


  //向ES中批量插入数据
  //参数1：批量操作的数据   参数2：索引名称
  def bulkInsert(sourceList:List[(String,Any)],indexName:String): Unit ={
    if(sourceList!=null && sourceList.size>0){
      //获取操作对象
      val jest: JestClient = getClient
      //构造批次操作
      val bulkBuild: Bulk.Builder = new Bulk.Builder
      //对批量操作的数据进行遍历
      for ((id,source) <- sourceList) {
        val index: Index = new Index.Builder(source)
          .index(indexName)
          .`type`("_doc")
          .id(id)
          .build()
        //将每条数据添加到批量操作中
        bulkBuild.addAction(index)
      }

      //Bulk是Action的实现类，主要实现批量操作
      val bulk: Bulk = bulkBuild.build()
      //执行批量操作  获取执行结果
      val result: BulkResult = jest.execute(bulk)
      //通过执行结果  获取批量插入的数据
      val items: java.util.List[BulkResult#BulkResultItem] = result.getItems
      println("保存到ES" + items.size() + "条数")
      //关闭连接
      jest.close()
    }
  }

  //从ES中查询数据
  def queryIndex(): Unit ={
    //获取操作对象
    val jest: JestClient = getClient

    //查询常用有两个实现类 Get通过id获取单个Document，以及Search处理复杂查询
    val query =
      """
        |{
        |  "query": {
        |    "bool": {
        |       "must": [
        |        {"match": {
        |          "name": "red"
        |        }}
        |      ],
        |      "filter": [
        |        {"term": { "actorList.name.keyword": "zhang cuishan"}}
        |      ]
        |    }
        |  },
        |  "from": 0,
        |  "size": 20,
        |  "sort": [
        |    {
        |      "doubanScore": {
        |        "order": "desc"
        |      }
        |    }
        |  ],
        |  "highlight": {
        |    "fields": {
        |      "name": {}
        |    }
        |  }
        |}
    """.stripMargin
    val search: Search = new Search.Builder(query)
      .addIndex("movie_index")
      .build()
    //执行操作
    val result: SearchResult = jest.execute(search)
    //获取命中的结果  sourceType:对命中的数据进行封装，因为是Json，所以我们用map封装
    //注意：一定得是Java的Map类型
    val rsList: java.util.List[SearchResult#Hit[java.util.Map[String, Any], Void]] = result.getHits(classOf[java.util.Map[String,Any]])

    //将Java转换为Scala集合，方便操作
    import scala.collection.JavaConverters._
    //获取Hit中的source部分
    val list: List[java.util.Map[String, Any]] = rsList.asScala.map(_.source).toList
    println(list.mkString("\n"))
    //关闭连接
    jest.close()
  }

  def main(args: Array[String]): Unit = {
    queryIndex()
  }

}
